#include <iostream>
#include <memory>

using namespace std;

class AbstractProduct {
public:
    AbstractProduct() {
        cout << __func__ << endl;
    }
    virtual ~AbstractProduct() {
        cout << __func__ << endl;
    };

    virtual void use() = 0;
};

class ConcreteProductA : public AbstractProduct {
public:
    ConcreteProductA() {
        cout << __func__ << endl;
    }
    ~ConcreteProductA() {
        cout << __func__ << endl;
    }

    void use() override {
        cout << "Concrete Product A : " << __func__ << endl;
    }
};

class ConcreteProductB : public AbstractProduct {
public:
    ConcreteProductB() {
        cout << __func__ << endl;
    }
    ~ConcreteProductB() {
        cout << __func__ << endl;
    }

    void use() override {
        cout << "Concrete Product B : " << __func__ << endl;
    }
};

class Factory {
public:
    static shared_ptr<AbstractProduct> create(string name) {
        if (name == "A") {
            return make_shared<ConcreteProductA>();
        } else if (name == "B") {
            return make_shared<ConcreteProductB>();
        } else {
            return nullptr;
        }
    }
};

int main(int argc, char *argv[])
{
    auto a = Factory::create("A");
    auto b = Factory::create("B");

    a->use();

    b->use();

    return 0;
}

